package org.example.ams.task.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.example.ams.entity.system.SysScheduled;
import org.example.ams.util.SpringContextUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

/**
 * 定时任务，用来执行指定taskBean的方法
 * 通过查询数据库，获取到任务的id的任务方法名，然后通过反射创建出任务实例，然后执行任务方法
 */
@Slf4j
@Data
public class SchedulingTask implements Runnable {
    private String scheduledId;
    private String beanId;
    private String methodName;
    private String params;


    public SchedulingTask(SysScheduled sysScheduled) {
        this.scheduledId =sysScheduled.getId();
        this.beanId = sysScheduled.getBeanId();
        this.methodName = sysScheduled.getMethodName();
        this.params = sysScheduled.getMethodParam();
    }

    @Override
    public void run() {
        log.info("定时任务开始执行 - beanId: {},方法： {}，参数： {}",beanId,methodName,params);
        long startTime = System.currentTimeMillis();
        try {
            Object bean  = SpringContextUtils.getBean(beanId);
            Method method = null;
            if (params != null && !params.equals("")) {
                method = bean.getClass().getDeclaredMethod(methodName, String.class);
                // 暴力反射 ,底层 method.setAccessible(true);
                ReflectionUtils.makeAccessible(method);
                method.invoke(bean,params);
            } else {
                method = bean.getClass().getDeclaredMethod(methodName);
                ReflectionUtils.makeAccessible(method);
                method.invoke(bean);
            }
            long times = System.currentTimeMillis() - startTime;
            log.info("定时任务执行结束 - bean：{}，方法：{}，参数：{}，耗时：{} 毫秒", beanId, methodName, params, times);
        }catch (Exception e) {
            e.printStackTrace();
            log.error(String.format("定时任务执行异常 - bean: %s, 方法： %s, 参数： %s",beanId,methodName,params));
        }
    }
}
